package com.xtm.exercise.base.A05Date;

import org.junit.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;


public class LocalDateTimeDemo {
    /**
     * 1.LocalDateTime介绍
     * https://blog.csdn.net/qq_33220089/article/details/127036870
     *
     * Java的Date，Calendar类型使用起来并不是很方便，而且Date类(据说)有着线程不安全等诸多弊端。同时若不进行封装，会在每次使用时特别麻烦。
     * 于是Java8推出了线程安全、简易、高可靠的时间包。并且数据库中也支持LocalDateTime类型，在数据存储时候使时间变得简单。
     * Java8这次新推出的包括三个相关的时间类型：LocalDateTime年月日十分秒；LocalDate日期；LocalTime时间；三个包的方法都差不多。
     *
     * 相关说明
     * Instant         时间戳
     * Duration        持续时间、时间差
     * LocalDate       只包含日期，比如：2018-09-24
     * LocalTime       只包含时间，比如：10:32:10
     * LocalDateTime   包含日期和时间，比如：2018-09-24 10:32:10
     * Peroid          时间段
     * ZoneOffset      时区偏移量，比如：+8:00
     * ZonedDateTime   带时区的日期时间
     * Clock           时钟，可用于获取当前时间戳
     * java.time.format.DateTimeFormatter      时间格式化类
     */
    //日期
    @Test
    public void test02(){
        // 获取当前日期和时间，包含日期和时间    LocalDateTime ： 当前日期和时间  LocalDate ： 当前日期  LocalTime ： 当前时间
        LocalDate date = LocalDate.now();
        LocalTime time = LocalTime.now();
        LocalDateTime now = LocalDateTime.now();
        LocalDate localDate = now.toLocalDate();

        // 时间戳转LocalDateTime
//        long timestamp = System.currentTimeMillis();
        // LocalDateTime 转化 时间戳timestamp
        long timestamp = now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        // 时间戳 转化 LocalDateTime
        LocalDateTime localDateTime1 = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();

        // LocalDateTime 转化 Date
        Date transDate = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
        // Date 转化 LocalDateTime
        LocalDateTime localDateTime = transDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

        // 日期和字符串的相互转换  format
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 日期时间转字符串
        String nowStr = now.format(fmt);
        // 字符串转日期时间  parse
        LocalDateTime localDateTime2 = LocalDateTime.parse(nowStr, fmt);

        // 获得某天最大时间 2023-08-18 23:59:59
        LocalTime max = LocalTime.MAX;
        LocalDateTime maxTime = LocalDateTime.of(date, max);
        System.out.println("获得某天最大时间： " + fmt.format(maxTime));

        // 获得某天最小时间 2023-08-18 00:00:00
        LocalTime min = LocalTime.MIN;
        LocalDateTime minTime = LocalDateTime.of(date, min);
        System.out.println("获得某天最小时间： " + fmt.format(minTime));

        //构造指定日期
        //调用工厂方法LocalDate.of()创建任意日期， 该方法需要传入年、月、日做参数，返回对应的LocalDate实例。
        LocalDate date1 = LocalDate.of(2000, 1, 1);
        System.out.println("千禧年=" + date1);
        // 获取年月日信息  getYear
        System.out.printf("年=%d， 月=%d， 日=%d", date1.getYear(), date1.getMonthValue(), date1.getDayOfMonth());

        // 比较两个日期是否相等  equals
        LocalDate date3 = LocalDate.of(2018, 9, 24);
        System.out.println("日期是否相等=" + date1.equals(date3));

        // 日期时间比较  Java8提供了isAfter()、isBefore()用于判断当前日期时间和指定日期时间的比较
        if (date1.isAfter(date3)) {
            System.out.println("2019年已经过去了");
        }

        LocalDate date2 = LocalDate.of(2021, 1, 1);
        if (date1.isBefore(date3)) {
            System.out.println("2021年还未到来");
        }

        // LocalDateTime计算天数和时间差   Duration.between
        Duration duration = Duration.between(date1, date2);
        long days = duration.toDays();

//        日期时间计算
//　　　　Java8提供了新的plusXxx()方法用于计算日期时间增量值，替代了原来的add()方法。新的API将返回一个全新的日期时间示例，需要使用新的对象进行接收。
        // 时间增量
        LocalTime newTime = time.plusHours(2);
        System.out.println("newTime=" + newTime);
        // 日期增量
        LocalDate newDate = date.plus(1, ChronoUnit.WEEKS);
        System.out.println("newDate=" + newDate);
        // 日期减量
        LocalDate minus = date.minus(1, ChronoUnit.DAYS);
        System.out.println("减少天："+ minus);

    }

    /**
     * 将生日 19990202  转换为 1999-02-02  字符串转换
     */
    @Test
    public void test06(){
        // 使用预定义格式解析与格式化日期
        // 解析日期
        String dateText = "20180924";
        LocalDate date = LocalDate.parse(dateText, DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println("格式化之后的日期=" + date);

        // 格式化日期
        dateText = date.format(DateTimeFormatter.ISO_DATE);
        System.out.println("dateText=" + dateText);

        ///////////////////////////////////////////////////////////////////////////////
        String BirthStr = "20180924";
        String Birth = changerStr(BirthStr);
        System.out.println("字符串转换为："+Birth);
    }

    //日期格式转换  将生日 19990202  转换为 1999-02-02
    public String changerStr(String args){
        StringBuffer Birth=new StringBuffer(args);
        Birth.insert(6,"-");
        Birth.insert(4,"-");
        return Birth.toString();
    }

    /**
     * 请使用日期时间相关的API，计算出一个人已经出生了多少天。
     */
    @Test
    public void localDateTime(){
        String next = "1987-06-25 00:00:00";
        LocalDateTime  currentDate = LocalDateTime .now();
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        LocalDateTime  birthday = LocalDateTime.parse(next, timeFormatter);
        // LocalDateTime计算天数和时间差
        Duration duration = Duration.between(birthday, currentDate);
        long days = duration.toDays();
        long years = days/365;
        System.out.println(days);
        System.out.println(years);
    }

    @Test
    public void test01(){
        //日期格式转换 将生日 19990202 转换为 1999-02-02
        StringBuffer Birth=new StringBuffer("19990202");
        Birth.insert(6,"-");
        Birth.insert(4,"-");
        String string = Birth.toString();
        System.out.println(string);
    }

}
